export default class WebScoket {
  constructor(clientId, wsUrl, onMessage) {
    this.clientId = clientId;
    this.wsUrl = wsUrl;
    this.onMessage = onMessage;
    this.socket = null;
    this.reconnect = true;
    this.reconnectTime = 10000; // 每10秒重连一次
    this.reconnectTask = null;
    this.heartbeatTime = 30000; // 每30秒发一次心跳检查
    this.heartbeatTask = null;
    return this;
  }
  init() {
    if (window.WebSocket) {
      this.doConnect(this.onMessage);
    } else {
      alert("the browser does not support websocket protocol");
    }
  }
  doConnect() {
    this.socket = new WebSocket(this.wsUrl + "/" + this.clientId);
    this.socket.onopen = () => {
      this.reconnect = false;
      this.heartbeatTask = setInterval(() => { this.checkHeartbeat(); }, this.heartbeatTime);
      this.clearReconnectTask();
    };
    this.socket.onclose = () => {
      this.clearHeartbeatTask();
      this.reconnect = true;
      this.doReconnect(this.onMessage);
      console.log("...ws connection closure...");
    };
    this.socket.onerror = () => {
      this.clearHeartbeatTask();
      console.log("...an error has occured...");
    };
    this.socket.onmessage = this.onMessage;
  }
  doReconnect() {
    if (this.reconnect) {
      this.reconnectTask = setTimeout(() => {
        console.log('...ws reconnect...');
        this.init(this.clientId, this.wsUrl, this.onMessage);
      }, this.reconnectTime);
    }
  }
  doDisconnect() {
    this.clearHeartbeatTask();
    this.clearReconnectTask();
    this.socket.onclose = function () { };
    this.socket.close();
    this.socket = null;
  }
  send(message) {
    if (this.socket) {
      this.socket.send(message);
    } else {
      alert("websocket is already in closed");
    }
  }
  checkHeartbeat() {
    this.send(JSON.stringify({ clientId: this.clientId, type: 0, message: 'ping' }));
  }
  clearReconnectTask() {
    if (this.reconnectTask) {
      clearTimeout(this.reconnectTask);
      this.reconnectTask = null;
    }
  }
  clearHeartbeatTask() {
    if (this.heartbeatTask) {
      clearInterval(this.heartbeatTask);
      this.heartbeatTask = null;
    }
  }
}